from rest_framework import viewsets, exceptions
from rest_framework.decorators import action

from account.models import User
from account.serializers import UserStandardSerializer
from account.filters import UserFilter
from account.services import user_service
from log.services import log_service
from libs.simple_responses import api_success
from libs.decorators import required_data_fields, permission_required
from libs.enums import Permission, LogModule


class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserStandardSerializer
    filterset_class = UserFilter
    ordering_fields = ('id',)
    log_module = LogModule.USER.value

    @permission_required([Permission.USER_MANAGE.value])
    @required_data_fields(['username', 'password', 'name', 'role_ids'])
    def create(self, request, *args, **kwargs):
        user = user_service.create(request.data)
        role_ids = request.data.get('role_ids', [])
        user_service.update_roles(user, role_ids)
        data = UserStandardSerializer(user).data
        log_service.build_create_log(self.request.user, user, module=self.log_module, content=f'创建了用户：{user.name}')
        return api_success(data=data, result_status=201)

    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        if instance.id != request.user.id and Permission.USER_MANAGE.value not in instance.get_permissions():
            raise exceptions.PermissionDenied()
        return super().update(request, *args, **kwargs)

    def partial_update(self, request, *args, **kwargs):
        instance = self.get_object()
        if instance.id != request.user.id and Permission.USER_MANAGE.value not in instance.get_permissions():
            raise exceptions.PermissionDenied()
        if 'role_ids' in request.data:
            user_service.update_roles(instance, request.data.get('role_ids', []))
        return super().partial_update(request, *args, **kwargs)

    @action(methods=['get'], detail=False)
    def me(self, request, *args, **kwargs):
        user = request.user
        data = UserStandardSerializer(user).data
        return api_success(data)

    @required_data_fields(['old_password', 'new_password'])
    @action(methods=['post'], detail=False, url_path='change-password')
    def change_password(self, request, *args, **kwargs):
        user = request.user
        old_password = request.data.get('old_password')
        new_password = request.data.get('new_password')
        if not user.check_password(old_password):
            raise exceptions.ValidationError({'error': '旧密码有误'})
        user.set_password(new_password)
        user.save()
        return api_success({})

    @permission_required([Permission.USER_MANAGE.value])
    @required_data_fields(['user_id', 'new_password'])
    @action(methods=['post'], detail=False, url_path='reset-password')
    def reset_password(self, request, *args, **kwargs):
        user_id = request.data.get('user_id')
        new_password = request.data.get('new_password')
        user = user_service.get(user_id)
        user.set_password(new_password)
        user.save()
        return api_success({})
